package main

import (
	"fmt"
	"gitee.com/ling-bin/network/Receivers"
	"gitee.com/ling-bin/network/netInterface"
	"gitee.com/ling-bin/network/netService"
	"log"
	_ "net/http/pprof"
	"runtime"
	"time"
)

func main() {
	//马力全开
	//runtime.GOMAXPROCS(runtime.NumCPU())
	/*	go func() {
		log.Println(http.ListenAndServe(":6060", nil))
	}()*/
	//addrs, err := net.InterfaceAddrs()
	//if err != nil {
	//	fmt.Println(err)
	//	os.Exit(1)
	//}
	addrs := []string{"[::]"}
	port := []string{"7015", "7016", "7017", "7018", "7019", "7020"} //监听端口
	addrAry := make([]string, 0, 5)
	for _, address := range addrs {
		for _, val := range port {
			addrAry = append(addrAry, address+":"+val)
		}
	}
	config := netService.DefaultConfig("tcp", addrAry)
	Receivers.PackageMaxLen = 16 * 1024
	Receivers.PackageMinLen = 256
	config.KeepTime = time.Second * 100
	config.HDataCache = false
	service := netService.NewService(config)
	service.SetOnConnStart(func(connection netInterface.IConnection) {
		//connId := connection.GetConnId()
		//fmt.Println("[", connection.GetRemoteAddr().String(), "]新连接：", connId)
	})
	service.SetOnConnStop(func(connection netInterface.IConnection) {
		//connId := connection.GetConnId()
		//fmt.Println("[", connection.GetRemoteAddr().String(), "]连接关闭：", connId)
	})

	//设置接收到完整包回调
	service.SetOnReceive(func(connection netInterface.IConnection, data []byte) {
		//time.Sleep(time.Second*15)
		connId := connection.GetConnId()
		//fmt.Println(connId,":",len(data))
		fmt.Println("[", connection.GetRemoteAddr().String(), "][", connId, "]连接上传新数据：", len(data), "---", string(data))
		//sendBf := []byte(fmt.Sprint("(tcp ", connId, " service  ",len(data),"!)"))
		//err := connection.SendData(sendBf, "")
		//if err != nil {
		//	fmt.Println("[", connection.GetConnId(), "]调用下发异常：", err)
		//}
		//connection.Stop()
		//connection.SendDataCall(sendBf,"测试",nil, func(connection netInterface.IConnection, bytes []byte, b bool, s string, i interface{}, err error) {
		//
		//})
		//fmt.Println("启动时间：",connection.GetStartTime())
		//fmt.Println("心跳时间：",connection.GetHeartTime())
		//fmt.Println("上行信息：")
		//fmt.Println(connection.GetRecInfo())
		//fmt.Println("下行信息：")
		//fmt.Println(connection.GetRepInfo())

		//if len(data) != 8 {
		//	fmt.Println("长度不对")
		//}else {
		//atomic.AddInt64(&count,1)
		//}
	})

	//设置下发回调
	service.SetOnReply(func(connection netInterface.IConnection, data []byte, isOk bool, cmdCode string, param interface{}, err error) {
		//connId := connection.GetConnId()
		//fmt.Println("[",connection.GetRemoteA+ddr().String(),"][" , connId , "]连接下发数据[",connection.GetPackCount(),"]：" , len(data),"---",string(data))
		if !isOk {
			log.Println("[", connection.GetConnId(), "]数据下发异常：", err)
		}
		//fmt.Println("全局回调：",param)
	})
	//设置设备上传第一包创建分包算法
	service.SetHandleStrategy(func(connection netInterface.IConnection, bytes []byte) *netInterface.StrategyData {
		key := string(bytes[1:12])
		receiver := make([]netInterface.IReceiver, 0, 2)
		receiver = append(receiver, Receivers.NewSpliceSymbolReceiver(0x28, 0x29))
		return &netInterface.StrategyData{
			Key:       key,
			Receivers: receiver,
			ExtData: map[string]interface{}{
				"macid": key,
			},
		}
	})
	service.SetLogHandle(func(level netInterface.ErrLevel, msg ...interface{}) {
		switch level {
		case netInterface.Fatal:
			log.Panicln("[致命]", msg)
			break
		case netInterface.Error:
			log.Println("[错误]", msg)
			break
		case netInterface.Warn:
			log.Println("[警告]", msg)
			break
		case netInterface.Info:
			log.Println("[消息]", msg)
			break
		}
	})
	go func() {
		for {
			log.Println(
				"[---TCP---]启动时间:", service.GetStartTime().Format("2006-01-02 15:04:05"),
				" 连接数:", service.GetConnMgr().Count(),
				" 协程数：", runtime.NumGoroutine())
			var toMap = service.ToMap()
			for key, val := range toMap {
				log.Println(key, ":", val)
			}
			time.Sleep(time.Second * 2)
		}
	}()
	service.Start()
	select {}
}

func is2019(buffer []byte) bool {
	if buffer[8] == 0x00 && buffer[9] == 0x00 {
		dataType20 := (buffer[19] >> 4) & 0x0f
		pkType20 := buffer[19] & 0x0f
		if dataType20 >= 0 && dataType20 <= 4 && pkType20 >= 0 && pkType20 <= 3 {
			return true
		}
	}
	return false
}
